package com.major.crowd.mvc.config;

import com.major.crowd.constant.CrowdConstant;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.access.AccessDeniedHandler;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Configuration          //配置类
@EnableWebSecurity      //启用web环境下的权限配置功能
@EnableGlobalMethodSecurity(prePostEnabled = true)  //启用全局权限控制
public class WebAppSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private CrowdUserDetailsService userDetailsService;

    // 在这里放进容器，父容器中拿不到这个bean
    /*@Bean
    public BCryptPasswordEncoder getPasswordEncoder(){

        return new BCryptPasswordEncoder();
    }*/
    @Autowired
    private BCryptPasswordEncoder passwordEncoder;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        //auth.inMemoryAuthentication().withUser("lisi").password("123").roles("ADMIN");
        auth
                .userDetailsService(userDetailsService)
                .passwordEncoder(passwordEncoder)
        ;
    }

    @Override
    protected void configure(HttpSecurity security) throws Exception {
        security
                .authorizeRequests()	// 对请求进行授权
                .antMatchers("/security/to/login/page.html")	// 针对登录页进行设置
                .permitAll()			// 无条件访问上面这个资源
                .antMatchers("/index.jsp")
                .permitAll()

                .antMatchers("/bootstrap/**")	// 针对静态资源进行设置，无条件访问
                .permitAll()
                .antMatchers("/crowd/**")
                .permitAll()
                .antMatchers("/css/**")
                .permitAll()
                .antMatchers("/fonts/**")
                .permitAll()
                .antMatchers("/img/**")
                .permitAll()
                .antMatchers("/jquery/**")
                .permitAll()
                .antMatchers("/layer/**")
                .permitAll()
                .antMatchers("/script/**")
                .permitAll()
                .antMatchers("/ztree/**")       // 针对静态资源进行设置，无条件访问
                .permitAll()

                .antMatchers("/admin/get/page.html")
                .hasRole("管理员")
                .antMatchers("/role/save.json")
                .hasAuthority("role:add")
                //.hasAuthority("user:get")
                .anyRequest()
                .authenticated()// 除以上资源外，其他资源都需要权限

                .and()
                .exceptionHandling()
                .accessDeniedHandler(new AccessDeniedHandler() {

                    @Override
                    public void handle(HttpServletRequest request, HttpServletResponse response,
                                       AccessDeniedException accessDeniedException) throws IOException, ServletException {
                        request.setAttribute("exception", new Exception(CrowdConstant.MESSAGE_ACCESS_DENIED));
                        request.getRequestDispatcher("/WEB-INF/system-error.jsp").forward(request, response);
                    }
                })

                .and()
                .csrf()							                // 防跨站请求伪造功能
                .disable()						                // 禁用

                .formLogin()
                .loginPage("/admin/to/login/page.html")         // 指定登录页面
                .permitAll()
                .loginProcessingUrl("/security/do/login.html")  //指定处理登录请求的地址
                .permitAll()
                .defaultSuccessUrl("/admin/to/main/page.html")	// 指定登录成功后前往的地址
                .usernameParameter("loginAcct")	                // 账号的请求参数名称
                .passwordParameter("userPswd")	                // 密码的请求参数名称

                .and()
                .logout()						                // 开启退出登录功能
                .logoutUrl("/security/do/logout.html")			// 指定退出登录地址
                .logoutSuccessUrl("/admin/to/login/page.html")	// 指定退出成功以后前往的地址


                /*.antMatchers("/admin/get/page.html")	// 针对分页显示Admin数据设定访问控制
                // .hasRole("经理")					// 要求具备经理角色
                .access("hasRole('经理') OR hasAuthority('user:get')")	// 要求具备“经理”角色和“user:get”权限二者之一*/


        ;
    }
}
